/**  
 * @Title:  MyUtil.java   
 * @Package com.jdbc.test02   
 * @Description:    TODO(用一句话描述该文件做什么)   
 * @author: WuKangrong     
 * @date:   2018年8月23日 下午6:40:41   
 * @version V
 * @JDKversion:1.8.0
 * @Copyright: 2018  
*/
package com.jdbc.test02;

import java.sql.*;
import java.util.*;

/**   
 * @ClassName:  MyUtil   
 * @Description:TODO(这里用一句话描述这个类的作用)   
 * @author: WuKangrong 
 * @date:   2018年8月23日 下午6:40:41     
 * @Copyright: 2018 
 */
public class MyConnect {
	Scanner sc = new Scanner(System.in);
	/**   
	 * @Title: connectWithData   
	 * @Description: TODO(连接到数据库，返回数据库连接对象)   
	 * @param: @return
	 * @param: @throws Exception      
	 * @return: Connection      
	 * @throws   
	 */
	public Connection connectWithData() throws Exception {
		String strDirverName = "oracle.jdbc.OracleDriver";
		Class.forName(strDirverName);
		// (2) 获取数据库连接对象
		// 1521 数据库服务器监听的端口号；orcl：数据库名数据实例名
		String url = "jdbc:oracle:thin:@localhost:1521:orcl";// 数据库连接各个属性 url连接串  解析连接串：@前面固定写法；@后面是数据库服务器的ip地址或主机名；
		// 用户名
		String name = "admin_t";
		// 密码
		String psw = "123456";
		// 从驱动管理类中获取指定参数的数据库连接对象
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(url,name,psw);
		} catch (Exception e) {
			System.out.println("密码错误！");
		}
		return conn;//返回数据库连接对象
	}
	/**   
	 * @Title: GetData   
	 * @Description: TODO(查询数据并将数据转存到集合)   
	 * @param: @param fieldName
	 * @param: @return
	 * @param: @throws Exception      
	 * @return: List<Map<String,Object>>      
	 * @throws   
	 */
	public List<Map<String, Object>> GetData(List<String> fieldName) throws Exception{
		List<Map<String, Object>> list = new ArrayList<>();
		int getFlag = 0;//用于判断获取字段名的标记
		//通过数据库连接对象得到执行器
		Statement st = this.connectWithData().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
		System.out.println("请输入SQL语句查询:");
		String strSql = sc.nextLine();
		//执行器执行查询语句进行查询
		ResultSet rs = st.executeQuery(strSql);
		ResultSetMetaData rsmd = rs.getMetaData();//获取字段列信息
		int fieldCount = rsmd.getColumnCount();//获得字段数
		while(rs.next()) {
			Map<String, Object> map = new LinkedHashMap<>();
			for(int i = 1; i <= fieldCount; i++) {
				map.put(rsmd.getColumnName(i), rs.getObject(rsmd.getColumnName(i)));//前者为列名（字段名）后者是该字段的值
				getFlag++;
				if(getFlag <= fieldCount) {//当读取一遍字段名后不再添加
					fieldName.add(rsmd.getColumnName(i));
				}
			}
			list.add(map);
		}//此时所有数据已转存到List中 不再不要执行器 会占用资源 可以关闭
		rs.close();
		st.close();
		return list;
	}
	/**   
	 * @Title: showData   
	 * @Description: TODO(输出查询)   
	 * @param: @throws Exception      
	 * @return: void      
	 * @throws   
	 */
	public void showData() throws Exception {
		List<String> list = new ArrayList<>();//字段名集合
		List<Map<String, Object>> data = this.GetData(list);//数据集合
		for(String str : list) {//遍历输出字段名
			System.out.format("%15s", str);
		}
		System.out.println();
		for (Map<String, Object> map : data) {//遍历输出数据
			Set<?> s = map.keySet();
			for (Object object : s) {
				System.out.format("%15s",map.get(object));//控制格式输出
			}
			System.out.println();//每行数据输出结束后回车
		}
	}
	
	public static void main(String[] args) throws Exception {
		
		try {
			NewInstance.newInstance(MyConnect.class).showData();
		} catch (Exception e) {

		}
	}
}
